#include "LockFile.h"
#include <errno.h>
#include "Logger.h"
#include <stdio.h>


LockFile::LockFile(std::string nombre, TMODO modo) {

	if (nombre.empty()){
		fprintf(stderr,"NOMBRE VACIO!!!") ;
		exit(-1);
	}

	this->nombre = nombre;

	switch (modo) {
	case LECTURA:
		this->fd = open(this->nombre.c_str(), O_RDONLY);
		this->tipoLock = F_RDLCK;
		//Logger::instancia() << "LockFile::LockFile - Creando LockFile para lectura " << this->nombre  << eol;

		if (this->fd == -1){
			perror("open");
			fprintf(stderr,"ERROR:Lectura -file: %s - %s \n",this->nombre.c_str(),strerror(errno) ) ;
		}

		break;
	case ESCRITURA:
		this->fd = open(this->nombre.c_str(), O_CREAT | O_WRONLY, 0777);
		this->tipoLock = F_WRLCK;

		if (this->fd == -1){
			perror("open");

			fprintf(stderr,"ERROR:Escritura -file: %s - %s \n",this->nombre.c_str(), strerror(errno) ) ;

			this->fl.l_whence = SEEK_SET;
		}

		//Logger::instancia() << "LockFile::LockFile - Creando LockFile para escritura "
		//<< this->nombre << eol;
		break;
	}
	if (this->fd == -1){
		exit(-1);
	}
	this->fl.l_pid = getpid();

	this->lockActivo = false;
}

int LockFile::tomarLock() {
	//Logger::instancia() << "LockFile :: tomarLock - Tomando Lock para "
	//		<< this->nombre << eol;
	this->fl.l_type = this->tipoLock;
	//Espero por el lock de manera bloqueante
	int resultado = fcntl(this->fd, F_SETLKW, &(this->fl));
	if (resultado == -1){
		perror("fcntl");

		fprintf(stderr,"LockFile::tomarLock - TomarLock - fd: %d - file: %s - %s \n",this->fd,this->nombre.c_str(), strerror(errno) ) ;
	}
	this->lockActivo = true;
	return resultado;
}

int LockFile::liberarLock() {
	//Logger::instancia() << "LockFile::liberarLock - Liberando LockFile para " << this->nombre  << eol;
	this->fl.l_type = F_UNLCK;
	int resultado = fcntl(this->fd, F_SETLK, &(this->fl));
	if (resultado == -1){
		perror("fcntl");

		fprintf(stderr,"LockFile::liberarLock - liberarLock -fd: %d - file: %s - %s \n",this->fd,this->nombre.c_str(), strerror(errno) ) ;
	}

	this->lockActivo = false;
	return resultado;
}
